package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.Employee;
import com.sky.entity.Setmeal;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DishServicelmpl implements DishService {
    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    DishMapper dishMapper;

    @Autowired
    DishFlavorMapper dishFlavorMapper;

    @Autowired
    SetmealMapper setmealMapper;

    @Autowired
    SetmealDishMapper setmealDishMapper;

    /*
     * 菜品分页+条件查询
     * */
    @Override
    public PageResult PageQuery(DishPageQueryDTO PageQueryDTO) {
        //1.使用PageHelepr实现分页查询，开启分页
        PageHelper.startPage(PageQueryDTO.getPage(), PageQueryDTO.getPageSize());

        //2.正常调用持久层mapper条件查询员工 (动态代理)
        Page page = (Page) dishMapper.selectByCondition(PageQueryDTO);

        //3.封装查询结果
        PageResult pageResult = new PageResult();
        pageResult.setTotal(page.getTotal());
        pageResult.setRecords(page.getResult());
        return pageResult;
    }

    /*
     * 菜品添加
     * */
    @Override
    public void saveAndFlavor(DishDTO dishDTO) {
        //1.调用dishMapper向菜品表中添加菜品信息（一条菜品数据）(设置主键返回)
        Dish addDish = new Dish();
        BeanUtils.copyProperties(dishDTO, addDish);
        dishMapper.insert(addDish);

        //2.调用dishMapper向菜品口味表中添加菜品口味信息（多条菜品口味数据）
        //设置当前菜品口味的菜品id（设置口味的归属）

        List<DishFlavor> flavors = dishDTO.getFlavors();
        flavors.forEach(dishFlavor -> {
            dishFlavor.setDishId(addDish.getId());
        });
        dishFlavorMapper.insertBatch(flavors);
    }

    /**
     * 根据id查询菜品和对应的口味数据
     *
     * @param id
     * @return
     */
    public DishVO getByIdWithFlavor(Long id) {
        //根据id查询菜品数据
        Dish dish = dishMapper.getById(id);

        //根据菜品id查询口味数据
        List<DishFlavor> dishFlavors = dishFlavorMapper.getByDishId(id);//后绪步骤实现

        //将查询到的数据封装到VO
        DishVO dishVO = new DishVO();
        BeanUtils.copyProperties(dish, dishVO);
        dishVO.setFlavors(dishFlavors);

        return dishVO;
    }


    /**
     * 更新菜品信息
     *
     * @param dishDTO
     */
    @Transactional
    @Override
    public void updateDish(DishDTO dishDTO) {
        //1.更新菜品信息
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        dishMapper.update(dish); //持久层操作entity，实体类职责划分更清晰，方便aop进行增强

        //2.删除当前菜品所有的口味
        dishFlavorMapper.deleteByDishId(Arrays.asList(dish.getId()));

        //需要更新口味
        //3. 批量添加当前菜品新的口味
        List<DishFlavor> flavors = dishDTO.getFlavors();

        if (flavors != null && flavors.size() > 0) {
            flavors.forEach(dishTtem -> {
                dishTtem.setDishId(dishDTO.getId());//注意：需要设置菜品口味
            });
        }

        dishFlavorMapper.insertBatch(flavors);
    }


    /**
     * 菜品批量删除
     *
     * @param ids
     */
    @Transactional
    @Override
    public void deleteBatch(List<Long> ids) {
        //1.判断当前菜品是否起售中
        //1.1 查询待删除的菜品数量：seletc count(*) from dish where status = 1 and id in(...)
        Integer startCount = dishMapper.countByStatus(ids);
        //1.2 判断是否存在，如果存在，则禁止删除菜品操作
        if (startCount != null && startCount > 0) {
            throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
        }
        //2. 判断当前菜品是否和套餐关联
        //2.1 查询待删除的菜品中是否与套餐关联的数量：select count(*) from setmeal_dish whee dish
        Integer dishCount = setmealDishMapper.countByDishId(ids);
        //2.2 判断是否存在，如果存在，则执行删除菜品操作
        if (dishCount != null && dishCount > 0) {
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);

        }

        //3. 删除菜品：delete from dish where id in(...)
        dishMapper.deleteById(ids);

        //4.
        dishFlavorMapper.deleteByDishId(ids);
    }

    /**
     * 菜品起售停售
     *
     * @param status
     * @param id
     */
    @Transactional
    public void startOrStop(Integer status, Long id) {
        Dish dish = Dish.builder()
                .id(id)
                .status(status)
                .build();
        dishMapper.update(dish);

        if (status == StatusConstant.DISABLE) {
            // 如果是停售操作，还需要将包含当前菜品的套餐也停售
            List<Long> dishIds = new ArrayList<>();
            dishIds.add(id);
            // select setmeal_id from setmeal_dish where dish_id in (?,?,?)
            List<Long> setmealIds = setmealDishMapper.getSetmealIdsByDishIds(dishIds);
            if (setmealIds != null && setmealIds.size() > 0) {
                for (Long setmealId : setmealIds) {
                    Setmeal setmeal = Setmeal.builder()
                            .id(setmealId)
                            .status(StatusConstant.DISABLE)
                            .build();
                    setmealMapper.update(setmeal);
                }
            }
        }
    }

    /**
     * 根据分类id查询菜品
     *
     * @param categoryId
     * @return
     */
    public List<DishVO> list(Long categoryId) {
        Dish dish = Dish.builder()
                .categoryId(categoryId)
                .status(StatusConstant.ENABLE)
                .build();
        //1.查询指定分类下的菜品列表
        List<Dish> list = dishMapper.list(dish);

        //2.遍历菜品列表集合，查询每一道菜的口味列表
        List<DishVO> dishVoList = list.stream().map(dishItem -> {
            //查询菜品的口味列表
            List<DishFlavor> dishFlavors = dishFlavorMapper.getByDishId(dishItem.getId());
            //封装菜和口味列表到DishVo
            DishVO dishVO = new DishVO();
            BeanUtils.copyProperties(dishItem, dishVO);
            dishVO.setFlavors(dishFlavors);
            return dishVO;
        }).collect(Collectors.toList());
        //3.返回封装List<DishVO>
        return dishVoList;
    }

}